"""Tests for hyp2f1 for complex values.

Author: Albert Steppi, with credit to Adam Kullberg (FormerPhycisist) for
the implementation of mp_hyp2f1 below, which modifies mpmath's hyp2f1 to
return the same branch as scipy's on the standard branch cut.
"""

import sys
import pytest
import numpy as np
from typing import NamedTuple
from numpy.testing import assert_allclose

from scipy.special import hyp2f1
from scipy.special._testutils import check_version, MissingModule


try:
    import mpmath
except ImportError:
    mpmath = MissingModule("mpmath")


def mp_hyp2f1(a, b, c, z):
    """Return mpmath hyp2f1 calculated on same branch as scipy hyp2f1.

    For most values of a,b,c mpmath returns the x - 0j branch of hyp2f1 on the
    branch cut x=(1,inf) whereas scipy's hyp2f1 calculates the x + 0j branch.
    Thus, to generate the right comparison values on the branch cut, we
    evaluate mpmath.hyp2f1 at x + 1e-15*j.

    The exception to this occurs when c-a=-m in which case both mpmath and
    scipy calculate the x + 0j branch on the branch cut. When this happens
    mpmath.hyp2f1 will be evaluated at the original z point.
    """
    on_branch_cut = z.real > 1.0 and abs(z.imag) < 1.0e-15
    cond1 = abs(c - a - round(c - a)) < 1.0e-15 and round(c - a) <= 0
    cond2 = abs(c - b - round(c - b)) < 1.0e-15 and round(c - b) <= 0
    # Make sure imaginary part is *exactly* zero
    if on_branch_cut:
        z = z.real + 0.0j
    if on_branch_cut and not (cond1 or cond2):
        z_mpmath = z.real + 1.0e-15j
    else:
        z_mpmath = z
    return complex(mpmath.hyp2f1(a, b, c, z_mpmath))


class Hyp2f1TestCase(NamedTuple):
    a: float
    b: float
    c: float
    z: complex
    expected: complex
    rtol: float


class TestHyp2f1:
    """Tests for hyp2f1 for complex values.

    Expected values for test cases were computed using mpmath. See
    `scipy.special._precompute.hyp2f1_data`. The verbose style of specifying
    test cases is used for readability and to make it easier to mark individual
    cases as expected to fail. Expected failures are used to highlight cases
    where improvements are needed. See
    `scipy.special._precompute.hyp2f1_data.make_hyp2f1_test_cases` for a
    function to generate the boilerplate for the test cases.

    Assertions have been added to each test to ensure that the test cases match
    the situations that are intended. A final test `test_test_hyp2f1` checks
    that the expected values in the test cases actually match what is computed
    by mpmath. This test is marked slow even though it isn't particularly slow
    so that it won't run by default on continuous integration builds.
    """
    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=0.2,
                    c=-10,
                    z=0.2 + 0.2j,
                    expected=np.inf + 0j,
                    rtol=0
                )
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=0.2,
                    c=-10,
                    z=0 + 0j,
                    expected=1 + 0j,
                    rtol=0
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=0,
                    c=-10,
                    z=0.2 + 0.2j,
                    expected=1 + 0j,
                    rtol=0
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=0,
                    c=0,
                    z=0.2 + 0.2j,
                    expected=1 + 0j,
                    rtol=0,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=0.2,
                    c=0,
                    z=0.2 + 0.2j,
                    expected=np.inf + 0j,
                    rtol=0,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=0.2,
                    c=0,
                    z=0 + 0j,
                    expected=np.nan + 0j,
                    rtol=0,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=-5,
                    c=-10,
                    z=0.2 + 0.2j,
                    expected=(1.0495404166666666+0.05708208333333334j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=-10,
                    c=-10,
                    z=0.2 + 0.2j,
                    expected=(1.092966013125+0.13455014673750001j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-10,
                    b=-20,
                    c=-10,
                    z=0.2 + 0.2j,
                    expected=(-0.07712512000000005+0.12752814080000005j),
                    rtol=1e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1,
                    b=3.2,
                    c=-1,
                    z=0.2 + 0.2j,
                    expected=(1.6400000000000001+0.6400000000000001j),
                    rtol=1e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-2,
                    b=1.2,
                    c=-4,
                    z=1 + 0j,
                    expected=1.8200000000000001 + 0j,
                    rtol=1e-15,
                ),
            ),
        ]
    )
    def test_c_non_positive_int(self, hyp2f1_test_case):
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=0.2,
                    c=1.5,
                    z=1 + 0j,
                    expected=1.1496439092239847 + 0j,
                    rtol=1e-15
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=12.3,
                    b=8.0,
                    c=20.31,
                    z=1 + 0j,
                    expected=69280986.75273195 + 0j,
                    rtol=1e-15
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=290.2,
                    b=321.5,
                    c=700.1,
                    z=1 + 0j,
                    expected=1.3396562400934e117 + 0j,
                    rtol=1e-12,
                ),
            ),
            # Note that here even mpmath produces different results for
            # results that should be equivalent.
            pytest.param(
                Hyp2f1TestCase(
                    a=9.2,
                    b=621.5,
                    c=700.1,
                    z=(1+0j),
                    expected=(952726652.4158565+0j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=621.5,
                    b=9.2,
                    c=700.1,
                    z=(1+0j),
                    expected=(952726652.4160284+0j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-101.2,
                    b=-400.4,
                    c=-172.1,
                    z=(1+0j),
                    expected=(2.2253618341394838e+37+0j),
                    rtol=1e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-400.4,
                    b=-101.2,
                    c=-172.1,
                    z=(1+0j),
                    expected=(2.2253618341394838e+37+0j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=172.5,
                    b=-201.3,
                    c=151.2,
                    z=(1+0j),
                    expected=(7.072266653650905e-135+0j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-201.3,
                    b=172.5,
                    c=151.2,
                    z=(1+0j),
                    expected=(7.072266653650905e-135+0j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-102.1,
                    b=-20.3,
                    c=1.3,
                    z=1 + 0j,
                    expected=2.7899070752746906e22 + 0j,
                    rtol=3e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-202.6,
                    b=60.3,
                    c=1.5,
                    z=1 + 0j,
                    expected=-1.3113641413099326e-56 + 0j,
                    rtol=1e-12,
                ),
            ),
        ],
    )
    def test_unital_argument(self, hyp2f1_test_case):
        """Tests for case z = 1, c - a - b > 0.

        Expected answers computed using mpmath.
        """
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert z == 1 and c - a - b > 0  # Tests the test
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=0.5,
                    b=0.2,
                    c=1.3,
                    z=-1 + 0j,
                    expected=0.9428846409614143 + 0j,
                    rtol=1e-15),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=12.3,
                    b=8.0,
                    c=5.300000000000001,
                    z=-1 + 0j,
                    expected=-4.845809986595704e-06 + 0j,
                    rtol=1e-15
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=221.5,
                    b=90.2,
                    c=132.3,
                    z=-1 + 0j,
                    expected=2.0490488728377282e-42 + 0j,
                    rtol=1e-7,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-102.1,
                    b=-20.3,
                    c=-80.8,
                    z=-1 + 0j,
                    expected=45143784.46783885 + 0j,
                    rtol=1e-7,
                ),
                marks=pytest.mark.xfail(
                    condition=sys.maxsize < 2**32,
                    reason="Fails on 32 bit.",
                )
            ),
        ],
    )
    def test_special_case_z_near_minus_1(self, hyp2f1_test_case):
        """Tests for case z ~ -1, c ~ 1 + a - b

        Expected answers computed using mpmath.
        """
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert abs(1 + a - b - c) < 1e-15 and abs(z + 1) < 1e-15
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=-4,
                    b=2.02764642551431,
                    c=1.0561196186065624,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(0.0031961077109535375-0.0011313924606557173j),
                    rtol=1e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-8,
                    b=-7.937789122896016,
                    c=-15.964218273004214,
                    z=(2-0.10526315789473695j),
                    expected=(0.005543763196412503-0.0025948879065698306j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-8,
                    b=8.095813935368371,
                    c=4.0013768449590685,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(-0.0003054674127221263-9.261359291755414e-05j),
                    rtol=1e-10,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-4,
                    b=-3.956227226099288,
                    c=-3.9316537064827854,
                    z=(1.1578947368421053-0.3157894736842106j),
                    expected=(-0.0020809502580892937-0.0041877333232365095j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=-4,
                    c=2.050308316530781,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(0.0011282435590058734+0.0002027062303465851j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=-8,
                    c=-15.964218273004214,
                    z=(1.3684210526315788+0.10526315789473673j),
                    expected=(-9.134907719238265e-05-0.00040219233987390723j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=-4,
                    c=4.0013768449590685,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(-0.000519013062087489-0.0005855883076830948j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-10000,
                    b=2.2,
                    c=93459345.3,
                    z=(2+2j),
                    expected=(0.9995292071559088-0.00047047067522659253j),
                    rtol=1e-12,
                ),
            ),
        ]
    )
    def test_a_b_negative_int(self, hyp2f1_test_case):
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert a == int(a) and a < 0 or b == int(b) and b < 0  # Tests the test
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.5,
                    b=-0.9629749245209605,
                    c=-15.5,
                    z=(1.1578947368421053-1.1578947368421053j),
                    expected=(0.9778506962676361+0.044083801141231616j),
                    rtol=3e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.5,
                    b=-3.9316537064827854,
                    c=1.5,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(4.0793167523167675-10.11694246310966j),
                    rtol=6e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.5,
                    b=-0.9629749245209605,
                    c=2.5,
                    z=(1.1578947368421053-0.10526315789473695j),
                    expected=(-2.9692999501916915+0.6394599899845594j),
                    rtol=1e-11,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.5,
                    b=-0.9629749245209605,
                    c=-15.5,
                    z=(1.5789473684210522-1.1578947368421053j),
                    expected=(0.9493076367106102-0.04316852977183447j),
                    rtol=1e-11,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-0.5,
                    c=-15.5,
                    z=(0.5263157894736841+0.10526315789473673j),
                    expected=(0.9844377175631795-0.003120587561483841j),
                    rtol=1e-10,
                ),
            ),
        ],
    )
    def test_a_b_neg_int_after_euler_hypergeometric_transformation(
        self, hyp2f1_test_case
    ):
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert (  # Tests the test
            (abs(c - a - int(c - a)) < 1e-15 and c - a < 0) or
            (abs(c - b - int(c - b)) < 1e-15 and c - b < 0)
        )
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-0.9629749245209605,
                    c=-15.963511401609862,
                    z=(0.10526315789473673-0.3157894736842106j),
                    expected=(0.9941449585778349+0.01756335047931358j),
                    rtol=1e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=-0.9629749245209605,
                    c=-15.963511401609862,
                    z=(0.5263157894736841+0.5263157894736841j),
                    expected=(1.0388722293372104-0.09549450380041416j),
                    rtol=5e-11,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=1.0561196186065624,
                    c=-7.93846038215665,
                    z=(0.10526315789473673+0.7368421052631575j),
                    expected=(2.1948378809826434+24.934157235172222j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=16.088264119063613,
                    c=8.031683612216888,
                    z=(0.3157894736842106-0.736842105263158j),
                    expected=(-0.4075277891264672-0.06819344579666956j),
                    rtol=2e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=2.050308316530781,
                    c=8.031683612216888,
                    z=(0.7368421052631575-0.10526315789473695j),
                    expected=(2.833535530740603-0.6925373701408158j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=2.050308316530781,
                    c=4.078873014294075,
                    z=(0.10526315789473673-0.3157894736842106j),
                    expected=(1.005347176329683-0.3580736009337313j),
                    rtol=5e-16,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-0.9629749245209605,
                    c=-15.963511401609862,
                    z=(0.3157894736842106-0.5263157894736843j),
                    expected=(0.9824353641135369+0.029271018868990268j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-0.9629749245209605,
                    c=-159.63511401609862,
                    z=(0.3157894736842106-0.5263157894736843j),
                    expected=(0.9982436200365834+0.002927268199671111j),
                    rtol=1e-7,
                ),
                marks=pytest.mark.xfail(reason="Poor convergence.")
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=16.088264119063613,
                    c=8.031683612216888,
                    z=(0.5263157894736841-0.5263157894736843j),
                    expected=(-0.6906825165778091+0.8176575137504892j),
                    rtol=5e-13,
                ),
            ),
        ]
    )
    def test_region1(self, hyp2f1_test_case):
        """|z| < 0.9 and real(z) >= 0."""
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert abs(z) < 0.9 and z.real >= 0  # Tests the test
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=1.0561196186065624,
                    c=4.078873014294075,
                    z=(-0.3157894736842106+0.7368421052631575j),
                    expected=(0.7751915029081136+0.24068493258607315j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=16.088264119063613,
                    c=2.0397202577726152,
                    z=(-0.9473684210526316-0.3157894736842106j),
                    expected=(6.564549348474962e-07+1.6761570598334562e-06j),
                    rtol=5e-09,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=2.050308316530781,
                    c=16.056809865262608,
                    z=(-0.10526315789473695-0.10526315789473695j),
                    expected=(0.9862043298997204-0.013293151372712681j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=8.077282662161238,
                    c=16.056809865262608,
                    z=(-0.3157894736842106-0.736842105263158j),
                    expected=(0.16163826638754716-0.41378530376373734j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=2.050308316530781,
                    c=-0.906685989801748,
                    z=(-0.5263157894736843+0.3157894736842106j),
                    expected=(-6.256871535165936+0.13824973858225484j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=8.077282662161238,
                    c=-3.9924618758357022,
                    z=(-0.9473684210526316-0.3157894736842106j),
                    expected=(75.54672526086316+50.56157041797548j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=8.077282662161238,
                    c=-1.9631175993998025,
                    z=(-0.5263157894736843+0.5263157894736841j),
                    expected=(282.0602536306534-82.31597306936214j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.095813935368371,
                    b=-3.9316537064827854,
                    c=8.031683612216888,
                    z=(-0.5263157894736843-0.10526315789473695j),
                    expected=(5.179603735575851+1.4445374002099813j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=-7.949900487447654,
                    c=1.0651378143226575,
                    z=(-0.3157894736842106-0.9473684210526316j),
                    expected=(2317.623517606141-269.51476321010324j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=-1.92872979730171,
                    c=2.0397202577726152,
                    z=(-0.736842105263158-0.3157894736842106j),
                    expected=(29.179154096175836+22.126690357535043j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.095813935368371,
                    b=-3.9316537064827854,
                    c=-15.963511401609862,
                    z=(-0.736842105263158-0.10526315789473695j),
                    expected=(0.20820247892032057-0.04763956711248794j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=-15.964218273004214,
                    c=-1.9631175993998025,
                    z=(-0.3157894736842106-0.5263157894736843j),
                    expected=(-157471.63920142158+991294.0587828817j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.095813935368371,
                    b=-7.949900487447654,
                    c=-7.93846038215665,
                    z=(-0.10526315789473695-0.10526315789473695j),
                    expected=(0.30765349653210194-0.2979706363594157j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=1.0561196186065624,
                    c=8.031683612216888,
                    z=(-0.9473684210526316-0.10526315789473695j),
                    expected=(1.6787607400597109+0.10056620134616838j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=16.088264119063613,
                    c=4.078873014294075,
                    z=(-0.5263157894736843-0.736842105263158j),
                    expected=(7062.07842506049-12768.77955655703j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=16.088264119063613,
                    c=2.0397202577726152,
                    z=(-0.3157894736842106+0.7368421052631575j),
                    expected=(54749.216391029935-23078.144720887536j),
                    rtol=2e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=1.0561196186065624,
                    c=-0.906685989801748,
                    z=(-0.10526315789473695-0.10526315789473695j),
                    expected=(1.21521766411428-4.449385173946672j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.980848054962111,
                    b=4.0013768449590685,
                    c=-1.9631175993998025,
                    z=(-0.736842105263158+0.5263157894736841j),
                    expected=(19234693144.196907+1617913967.7294445j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=1.0561196186065624,
                    c=-15.963511401609862,
                    z=(-0.5263157894736843+0.3157894736842106j),
                    expected=(0.9345201094534371+0.03745712558992195j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=-0.9629749245209605,
                    c=2.0397202577726152,
                    z=(-0.10526315789473695+0.10526315789473673j),
                    expected=(0.605732446296829+0.398171533680972j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=-15.964218273004214,
                    c=2.0397202577726152,
                    z=(-0.10526315789473695-0.5263157894736843j),
                    expected=(-9.753761888305416-4.590126012666959j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=-1.92872979730171,
                    c=2.0397202577726152,
                    z=(-0.10526315789473695+0.3157894736842106j),
                    expected=(0.45587226291120714+1.0694545265819797j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-7.949900487447654,
                    c=-0.906685989801748,
                    z=(-0.736842105263158+0.3157894736842106j),
                    expected=(12.334808243233418-76.26089051819054j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-7.949900487447654,
                    c=-15.963511401609862,
                    z=(-0.5263157894736843+0.10526315789473673j),
                    expected=(1.2396019687632678-0.047507973161146286j),
                    rtol=1e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.980848054962111,
                    b=-0.9629749245209605,
                    c=-0.906685989801748,
                    z=(-0.3157894736842106-0.5263157894736843j),
                    expected=(97.7889554372208-18.999754543400016j),
                    rtol=5e-13,
                ),
            ),
        ]
    )
    def test_region2(self, hyp2f1_test_case):
        """|z| < 1 and real(z) < 0."""
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert abs(z) < 1 and z.real < 0  # Tests the test
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=16.25,
                    b=-3.75,
                    c=-3.5,
                    z=(0.5263157894736841+0.7368421052631575j),
                    expected=(-1279.4894322256655-2302.914821389276j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.75,
                    b=8.25,
                    c=-1.5,
                    z=(0.9473684210526314+0.3157894736842106j),
                    expected=(-8889.452798586273-11961.162305065242j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.25,
                    b=2.25,
                    c=-1.5,
                    z=(0.5263157894736841-0.736842105263158j),
                    expected=(-236.58971357952055-238.5228224781136j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.75,
                    b=-7.75,
                    c=-15.5,
                    z=(0.5263157894736841+0.7368421052631575j),
                    expected=(0.8116076584352279-0.29360565398246036j),
                    rtol=5e-16,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.25,
                    b=4.25,
                    c=-0.5,
                    z=(0.5263157894736841-0.736842105263158j),
                    expected=(-28.119407485189985+98.89858821348005j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.75,
                    b=2.25,
                    c=1.5,
                    z=(0.5263157894736841+0.7368421052631575j),
                    expected=(0.5311049067450484-0.9434347326448517j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.25,
                    b=-15.75,
                    c=-7.5,
                    z=(0.9473684210526314+0.10526315789473673j),
                    expected=(1262084.378141873+1775569.6338380123j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.75,
                    b=-7.75,
                    c=-15.5,
                    z=(0.5263157894736841-0.736842105263158j),
                    expected=(-0.009810480794804165+0.3648997569257999j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.25,
                    b=2.25,
                    c=-3.5,
                    z=(0.5263157894736841-0.736842105263158j),
                    expected=(585660.8815535795-33646.68398590896j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=-3.9316537064827854,
                    c=-15.963511401609862,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(181899621848365.2-173207123998705.7j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.75,
                    b=8.25,
                    c=-0.5,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(0.04271686244952705-0.14087902824639406j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=-1.92872979730171,
                    c=-0.906685989801748,
                    z=(0.9473684210526314-0.3157894736842106j),
                    expected=(-449.5119088817207+320.1423128036188j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=1.0561196186065624,
                    c=8.031683612216888,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(0.6361479738012501+0.028575620091205088j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.25,
                    b=16.25,
                    c=16.5,
                    z=(0.5263157894736841+0.7368421052631575j),
                    expected=(-0.9038811840552261-1.5356250756164884j),
                    rtol=1e-8,
                ),
                marks=pytest.mark.xfail(
                    reason="Unhandled parameters."
                )
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.25,
                    b=-1.75,
                    c=-1.5,
                    z=(0.9473684210526314+0.3157894736842106j),
                    expected=(653.0109150415394-4554.162605155542j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.75,
                    b=-3.75,
                    c=4.5,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(118.7009859241035-34.18713648654642j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.25,
                    b=-15.75,
                    c=-3.5,
                    z=(0.5263157894736841+0.7368421052631575j),
                    expected=(-540204.4774526551+4970059.109251281j),
                    rtol=1e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.25,
                    b=-15.75,
                    c=-0.5,
                    z=(0.5263157894736841-0.736842105263158j),
                    expected=(2253490.972258385+3318620.683390017j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.25,
                    b=-7.75,
                    c=-7.5,
                    z=(0.9473684210526314+0.3157894736842106j),
                    expected=(-46159826.46716958-17880663.82218242j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-7.949900487447654,
                    c=-7.93846038215665,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(0.07116833581404514+0.11823358038036977j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=4.0013768449590685,
                    c=-7.93846038215665,
                    z=(0.7368421052631575+0.5263157894736841j),
                    expected=(4.7724909620664006e+17-6.039064078946702e+16j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.25,
                    b=-7.75,
                    c=1.5,
                    z=(0.9473684210526314-0.10526315789473695j),
                    expected=(0.0188022179759303+0.002921737281641378j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=1.0561196186065624,
                    c=-7.93846038215665,
                    z=(0.7368421052631575-0.5263157894736843j),
                    expected=(-9203.462928334846+12390.110518017136j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.75,
                    b=-15.75,
                    c=8.5,
                    z=(0.7368421052631575+0.5263157894736841j),
                    expected=(6.468457061368628+24.190040684917374j),
                    rtol=6e-16,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=16.088264119063613,
                    c=2.0397202577726152,
                    z=(0.7368421052631575+0.5263157894736841j),
                    expected=(2408.3451340186543-4275.257316636014j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.75,
                    b=-7.75,
                    c=8.5,
                    z=(0.7368421052631575-0.5263157894736843j),
                    expected=(4.1379984626381345-5.183654781039423j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.25,
                    b=-7.75,
                    c=-0.5,
                    z=(0.5263157894736841+0.7368421052631575j),
                    expected=(-81177.775295738+56079.73286548954j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=2.050308316530781,
                    c=-0.906685989801748,
                    z=(0.9473684210526314+0.3157894736842106j),
                    expected=(1192868.5068926765+3624210.8182139914j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=-1.92872979730171,
                    c=8.031683612216888,
                    z=(0.5263157894736841+0.7368421052631575j),
                    expected=(1.8286341846195202+1.9295255682312178j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=1.0561196186065624,
                    c=16.056809865262608,
                    z=(0.7368421052631575-0.5263157894736843j),
                    expected=(1.0514645669696452-0.0430834059440128j),
                    rtol=5e-10,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=-15.964218273004214,
                    c=2.0397202577726152,
                    z=(0.5263157894736841+0.7368421052631575j),
                    expected=(541983.236432269+288200.2043029435j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.25,
                    b=8.25,
                    c=1.5,
                    z=(0.5263157894736841-0.736842105263158j),
                    expected=(-10.931988086039945+1.9136272843579096j),
                    rtol=1e-15,
                ),
            ),
        ]
    )
    def test_region3(self, hyp2f1_test_case):
        """0.9 <= |z| <= 1 and |1 - z| < 0.9."""
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert 0.9 <= abs(z) <= 1 and abs(1 - z) < 0.9  # Tests the test
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=16.25,
                    b=4.25,
                    c=2.5,
                    z=(0.4931034482758623-0.7965517241379311j),
                    expected=(38.41207903409937-30.510151276075792j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.0,
                    b=16.087593263474208,
                    c=16.088264119063613,
                    z=(0.5689655172413794-0.7965517241379311j),
                    expected=(-0.6667857912761286-1.0206224321443573j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.0,
                    b=1.0272592605282642,
                    c=-7.949900487447654,
                    z=(0.4931034482758623-0.7965517241379311j),
                    expected=(1679024.1647997478-2748129.775857212j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=16.0,
                    c=-7.949900487447654,
                    z=(0.4931034482758623-0.7965517241379311j),
                    expected=(424747226301.16986-1245539049327.2856j),
                    rtol=1e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=-15.964218273004214,
                    c=4.0,
                    z=(0.4931034482758623-0.7965517241379311j),
                    expected=(-0.0057826199201757595+0.026359861999025885j),
                    rtol=5e-06,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=-0.9629749245209605,
                    c=2.0397202577726152,
                    z=(0.5689655172413794-0.7965517241379311j),
                    expected=(0.4671901063492606+0.7769632229834897j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.0,
                    b=-3.956227226099288,
                    c=-7.949900487447654,
                    z=(0.4931034482758623+0.7965517241379312j),
                    expected=(0.9422283708145973+1.3476905754773343j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0,
                    b=-15.980848054962111,
                    c=-15.964218273004214,
                    z=(0.4931034482758623-0.7965517241379311j),
                    expected=(0.4168719497319604-0.9770953555235625j),
                    rtol=5e-10,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.5,
                    b=16.088264119063613,
                    c=2.5,
                    z=(0.5689655172413794+0.7965517241379312j),
                    expected=(1.279096377550619-2.173827694297929j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=4.0013768449590685,
                    c=2.0397202577726152,
                    z=(0.4931034482758623+0.7965517241379312j),
                    expected=(-2.071520656161738-0.7846098268395909j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=8.0,
                    c=-0.9629749245209605,
                    z=(0.5689655172413794-0.7965517241379311j),
                    expected=(-7.740015495862889+3.386766435696699j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=16.088264119063613,
                    c=-7.93846038215665,
                    z=(0.4931034482758623+0.7965517241379312j),
                    expected=(-6318.553685853241-7133.416085202879j),
                    rtol=5e-9,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.980848054962111,
                    b=-3.9316537064827854,
                    c=16.056809865262608,
                    z=(0.5689655172413794+0.7965517241379312j),
                    expected=(-0.8854577905547399+8.135089099967278j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=-0.9629749245209605,
                    c=4.078873014294075,
                    z=(0.4931034482758623+0.7965517241379312j),
                    expected=(1.224291301521487+0.36014711766402485j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.75,
                    b=-0.75,
                    c=-1.5,
                    z=(0.4931034482758623+0.7965517241379312j),
                    expected=(-1.5765685855028473-3.9399766961046323j),
                    rtol=1e-3,
                ),
                marks=pytest.mark.xfail(
                    reason="Unhandled parameters."
                )
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.980848054962111,
                    b=-1.92872979730171,
                    c=-7.93846038215665,
                    z=(0.5689655172413794-0.7965517241379311j),
                    expected=(56.794588688231194+4.556286783533971j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.5,
                    b=4.5,
                    c=2.050308316530781,
                    z=(0.5689655172413794+0.7965517241379312j),
                    expected=(-4.251456563455306+6.737837111569671j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.5,
                    b=8.5,
                    c=-1.92872979730171,
                    z=(0.4931034482758623-0.7965517241379311j),
                    expected=(2177143.9156599627-3313617.2748088865j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.5,
                    b=-1.5,
                    c=4.0013768449590685,
                    z=(0.4931034482758623-0.7965517241379311j),
                    expected=(0.45563554481603946+0.6212000158060831j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.5,
                    b=-7.5,
                    c=-15.964218273004214,
                    z=(0.4931034482758623+0.7965517241379312j),
                    expected=(61.03201617828073-37.185626416756214j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.5,
                    b=16.5,
                    c=4.0013768449590685,
                    z=(0.4931034482758623+0.7965517241379312j),
                    expected=(-33143.425963520735+20790.608514722644j),
                    rtol=1e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.5,
                    b=4.5,
                    c=-0.9629749245209605,
                    z=(0.5689655172413794+0.7965517241379312j),
                    expected=(30.778600270824423-26.65160354466787j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.5,
                    b=-3.5,
                    c=16.088264119063613,
                    z=(0.5689655172413794-0.7965517241379311j),
                    expected=(1.0629792615560487-0.08308454486044772j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.5,
                    b=-7.5,
                    c=-0.9629749245209605,
                    z=(0.4931034482758623-0.7965517241379311j),
                    expected=(17431.571802591767+3553.7129767034507j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.25,
                    b=8.25,
                    c=16.5,
                    z=(0.11379310344827598+0.9482758620689657j),
                    expected=(0.4468600750211926+0.7313214934036885j),
                    rtol=1e-3,
                ),
                marks=pytest.mark.xfail(
                    reason="Unhandled parameters."
                )
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.25,
                    b=16.25,
                    c=4.5,
                    z=(0.3413793103448277+0.8724137931034486j),
                    expected=(-3.905704438293991+3.693347860329299j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.25,
                    b=4.25,
                    c=-0.5,
                    z=(0.11379310344827598-0.9482758620689655j),
                    expected=(-40.31777941834244-89.89852492432011j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=8.0,
                    c=-15.964218273004214,
                    z=(0.11379310344827598-0.9482758620689655j),
                    expected=(52584.347773055284-109197.86244309516j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.095813935368371,
                    b=-15.964218273004214,
                    c=16.056809865262608,
                    z=(0.03793103448275881+0.9482758620689657j),
                    expected=(-1.187733570412592-1.5147865053584582j),
                    rtol=5e-10,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=-3.9316537064827854,
                    c=1.0651378143226575,
                    z=(0.26551724137931054+0.9482758620689657j),
                    expected=(13.077494677898947+35.071599628224966j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=-3.5,
                    c=-3.5,
                    z=(0.26551724137931054+0.8724137931034486j),
                    expected=(-0.5359656237994614-0.2344483936591811j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.25,
                    b=-3.75,
                    c=-1.5,
                    z=(0.26551724137931054+0.9482758620689657j),
                    expected=(1204.8114871663133+64.41022826840198j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=16.0,
                    c=4.0013768449590685,
                    z=(0.03793103448275881-0.9482758620689655j),
                    expected=(-9.85268872413994+7.011107558429154j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=16.0,
                    c=4.0013768449590685,
                    z=(0.3413793103448277-0.8724137931034484j),
                    expected=(528.5522951158454-1412.21630264791j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.5,
                    b=1.0561196186065624,
                    c=-7.5,
                    z=(0.4172413793103451+0.8724137931034486j),
                    expected=(133306.45260685298+256510.7045225382j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=8.077282662161238,
                    c=-15.963511401609862,
                    z=(0.3413793103448277-0.8724137931034484j),
                    expected=(-0.998555715276967+2.774198742229889j),
                    rtol=5e-11,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.75,
                    b=-0.75,
                    c=1.5,
                    z=(0.11379310344827598-0.9482758620689655j),
                    expected=(2.072445019723025-2.9793504811373515j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.5,
                    b=-1.92872979730171,
                    c=1.5,
                    z=(0.11379310344827598-0.9482758620689655j),
                    expected=(-41.87581944176649-32.52980303527139j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.75,
                    b=-15.75,
                    c=-0.5,
                    z=(0.11379310344827598-0.9482758620689655j),
                    expected=(-3729.6214864209774-30627.510509112635j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=-15.964218273004214,
                    c=-0.906685989801748,
                    z=(0.03793103448275881+0.9482758620689657j),
                    expected=(-131615.07820609974+145596.13384245415j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.5,
                    b=16.5,
                    c=16.088264119063613,
                    z=(0.26551724137931054+0.8724137931034486j),
                    expected=(0.18981844071070744+0.7855036242583742j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.5,
                    b=8.5,
                    c=-3.9316537064827854,
                    z=(0.11379310344827598-0.9482758620689655j),
                    expected=(110224529.2376068+128287212.04290268j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.5,
                    b=-7.5,
                    c=4.0013768449590685,
                    z=(0.3413793103448277-0.8724137931034484j),
                    expected=(0.2722302180888523-0.21790187837266162j),
                    rtol=1.2e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.5,
                    b=-7.5,
                    c=-15.964218273004214,
                    z=(0.11379310344827598-0.9482758620689655j),
                    expected=(-2.8252338010989035+2.430661949756161j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.5,
                    b=16.5,
                    c=4.0013768449590685,
                    z=(0.03793103448275881+0.9482758620689657j),
                    expected=(-20.604894257647945+74.5109432558078j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.5,
                    b=8.5,
                    c=-0.9629749245209605,
                    z=(0.3413793103448277+0.8724137931034486j),
                    expected=(-2764422.521269463-3965966.9965808876j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.5,
                    b=-0.5,
                    c=1.0561196186065624,
                    z=(0.26551724137931054+0.9482758620689657j),
                    expected=(1.2262338560994905+0.6545051266925549j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.5,
                    b=-15.5,
                    c=-7.949900487447654,
                    z=(0.4172413793103451-0.8724137931034484j),
                    expected=(-2258.1590330318213+8860.193389158803j),
                    rtol=1.4e-10,
                ),
            ),
        ]
    )
    def test_region4(self, hyp2f1_test_case):
        """0.9 <= |z| <= 1 and |1 - z| >= 1.

        This region is unhandled by of the standard transformations and
        needs special care.
        """
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert 0.9 <= abs(z) <= 1 and abs(1 - z) >= 0.9  # Tests the test
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=4.5,
                    b=16.088264119063613,
                    c=8.5,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(0.018601324701770394-0.07618420586062377j),
                    rtol=5e-08,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.25,
                    b=4.25,
                    c=4.5,
                    z=(0.6448275862068968-0.8724137931034484j),
                    expected=(-1.391549471425551-0.118036604903893j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=2.050308316530781,
                    c=-1.9631175993998025,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(-2309.178768155151-1932.7247727595172j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=1.0,
                    c=-15.964218273004214,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(85592537010.05054-8061416766688.324j),
                    rtol=2e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.095813935368371,
                    b=-0.5,
                    c=1.5,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(1.2334498208515172-2.1639498536219732j),
                    rtol=5e-11,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=-15.964218273004214,
                    c=4.0,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(102266.35398605966-44976.97828737755j),
                    rtol=1e-3,
                ),
                marks=pytest.mark.xfail(
                    reason="Unhandled parameters."
                )
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.0,
                    b=-3.956227226099288,
                    c=-15.964218273004214,
                    z=(0.6448275862068968-0.8724137931034484j),
                    expected=(-2.9590030930007236-4.190770764773225j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=-15.5,
                    c=-7.5,
                    z=(0.5689655172413794-0.8724137931034484j),
                    expected=(-112554838.92074208+174941462.9202412j),
                    rtol=5e-05,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.980848054962111,
                    b=2.050308316530781,
                    c=1.0,
                    z=(0.6448275862068968-0.8724137931034484j),
                    expected=(3.7519882374080145+7.360753798667486j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=2.050308316530781,
                    c=4.0,
                    z=(0.6448275862068968-0.8724137931034484j),
                    expected=(0.000181132943964693+0.07742903103815582j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=4.0013768449590685,
                    c=-1.9631175993998025,
                    z=(0.5689655172413794+0.8724137931034486j),
                    expected=(386338.760913596-386166.51762171905j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.980848054962111,
                    b=8.0,
                    c=-1.92872979730171,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(1348667126.3444858-2375132427.158893j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.5,
                    b=-0.9629749245209605,
                    c=4.5,
                    z=(0.5689655172413794+0.8724137931034486j),
                    expected=(1.428353429538678+0.6472718120804372j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=-0.9629749245209605,
                    c=2.0397202577726152,
                    z=(0.5689655172413794-0.8724137931034484j),
                    expected=(3.1439267526119643-3.145305240375117j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=-15.964218273004214,
                    c=-7.93846038215665,
                    z=(0.6448275862068968-0.8724137931034484j),
                    expected=(75.27467675681773+144.0946946292215j),
                    rtol=1e-07,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.75,
                    b=-7.75,
                    c=-7.5,
                    z=(0.5689655172413794+0.8724137931034486j),
                    expected=(-0.3699450626264222+0.8732812475910993j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.5,
                    b=16.5,
                    c=1.0561196186065624,
                    z=(0.5689655172413794-0.8724137931034484j),
                    expected=(5.5361025821300665-2.4709693474656285j),
                    rtol=5e-09,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.5,
                    b=8.5,
                    c=-3.9316537064827854,
                    z=(0.6448275862068968-0.8724137931034484j),
                    expected=(-782805.6699207705-537192.581278909j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.5,
                    b=-15.5,
                    c=1.0561196186065624,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(12.345113400639693-14.993248992902007j),
                    rtol=0.0005,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.5,
                    b=-0.5,
                    c=-15.964218273004214,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(23.698109392667842+97.15002033534108j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.5,
                    b=16.5,
                    c=4.0013768449590685,
                    z=(0.6448275862068968-0.8724137931034484j),
                    expected=(1115.2978631811834+915.9212658718577j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.5,
                    b=16.5,
                    c=-0.9629749245209605,
                    z=(0.6448275862068968+0.8724137931034486j),
                    expected=(642077722221.6489+535274495398.21027j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.5,
                    b=-3.5,
                    c=4.0013768449590685,
                    z=(0.5689655172413794+0.8724137931034486j),
                    expected=(-5.689219222945697+16.877463062787143j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.5,
                    b=-1.5,
                    c=-0.9629749245209605,
                    z=(0.5689655172413794-0.8724137931034484j),
                    expected=(-44.32070290703576+1026.9127058617403j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.25,
                    b=2.25,
                    c=4.5,
                    z=(0.11379310344827598-1.024137931034483j),
                    expected=(-0.021965227124574663+0.009908300237809064j),
                    rtol=1e-3,
                ),
                marks=pytest.mark.xfail(
                    reason="Unhandled parameters."
                )
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.02764642551431,
                    b=1.5,
                    c=16.5,
                    z=(0.26551724137931054+1.024137931034483j),
                    expected=(1.0046072901244183+0.19945500134119992j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=1.0,
                    c=-3.9316537064827854,
                    z=(0.3413793103448277+0.9482758620689657j),
                    expected=(21022.30133421465+49175.98317370489j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=16.088264119063613,
                    c=-1.9631175993998025,
                    z=(0.4172413793103451-0.9482758620689655j),
                    expected=(-7024239.358547302+2481375.02681063j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.25,
                    b=-15.75,
                    c=1.5,
                    z=(0.18965517241379315+1.024137931034483j),
                    expected=(92371704.94848-403546832.548352j),
                    rtol=5e-06,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.5,
                    b=-7.949900487447654,
                    c=8.5,
                    z=(0.26551724137931054-1.024137931034483j),
                    expected=(1.9335109845308265+5.986542524829654j),
                    rtol=5e-10,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.095813935368371,
                    b=-1.92872979730171,
                    c=-7.93846038215665,
                    z=(0.4931034482758623+0.8724137931034486j),
                    expected=(-122.52639696039328-59.72428067512221j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.25,
                    b=-1.75,
                    c=-1.5,
                    z=(0.4931034482758623+0.9482758620689657j),
                    expected=(-90.40642053579428+50.50649180047921j),
                    rtol=5e-08,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.5,
                    b=8.077282662161238,
                    c=16.5,
                    z=(0.4931034482758623+0.9482758620689657j),
                    expected=(-0.2155745818150323-0.564628986876639j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=1.0561196186065624,
                    c=8.031683612216888,
                    z=(0.4172413793103451-0.9482758620689655j),
                    expected=(0.9503140488280465+0.11574960074292677j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.75,
                    b=2.25,
                    c=-15.5,
                    z=(0.4172413793103451+0.9482758620689657j),
                    expected=(0.9285862488442175+0.8203699266719692j),
                    rtol=5e-13,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.75,
                    b=4.25,
                    c=-15.5,
                    z=(0.3413793103448277-0.9482758620689655j),
                    expected=(-1.0509834850116921-1.1145522325486075j),
                    rtol=1.1e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=-0.9629749245209605,
                    c=2.0397202577726152,
                    z=(0.4931034482758623-0.9482758620689655j),
                    expected=(2.88119116536769-3.4249933450696806j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.5,
                    b=-15.964218273004214,
                    c=16.5,
                    z=(0.18965517241379315+1.024137931034483j),
                    expected=(199.65868451496038+347.79384207302877j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.75,
                    b=-15.75,
                    c=-3.5,
                    z=(0.4931034482758623-0.8724137931034484j),
                    expected=(-208138312553.07013+58631611809.026955j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=-15.5,
                    c=-7.5,
                    z=(0.3413793103448277+0.9482758620689657j),
                    expected=(-23032.90519856288-18256.94050457296j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.5,
                    b=1.5,
                    c=1.0561196186065624,
                    z=(0.4931034482758623-0.8724137931034484j),
                    expected=(1.507342459587056+1.2332023580148403j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=2.5,
                    b=4.5,
                    c=-3.9316537064827854,
                    z=(0.4172413793103451+0.9482758620689657j),
                    expected=(7044.766127108853-40210.365567285575j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.5,
                    b=-1.5,
                    c=1.0561196186065624,
                    z=(0.03793103448275881+1.024137931034483j),
                    expected=(0.2725347741628333-2.247314875514784j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.5,
                    b=-1.5,
                    c=-7.949900487447654,
                    z=(0.26551724137931054+1.024137931034483j),
                    expected=(-11.250200011017546+12.597393659160472j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.5,
                    b=8.5,
                    c=16.088264119063613,
                    z=(0.26551724137931054+1.024137931034483j),
                    expected=(-0.18515160890991517+0.7959014164484782j),
                    rtol=2e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.5,
                    b=16.5,
                    c=-3.9316537064827854,
                    z=(0.3413793103448277-1.024137931034483j),
                    expected=(998246378.8556538+1112032928.103645j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.5,
                    b=-3.5,
                    c=2.050308316530781,
                    z=(0.03793103448275881+1.024137931034483j),
                    expected=(0.5527670397711952+2.697662715303637j),
                    rtol=1.2e-15,       # rtol bumped from 1e-15 in gh18414
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-15.5,
                    b=-1.5,
                    c=-0.9629749245209605,
                    z=(0.4931034482758623-0.8724137931034484j),
                    expected=(55.396931662136886+968.467463806326j),
                    rtol=5e-14,
                ),
            ),
        ]
    )
    def test_region5(self, hyp2f1_test_case):
        """1 < |z| < 1.1 and |1 - z| >= 0.9 and real(z) >= 0"""
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert 1 < abs(z) < 1.1 and abs(1 - z) >= 0.9 and z.real >= 0
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            pytest.param(
                Hyp2f1TestCase(
                    a=8.095813935368371,
                    b=4.0013768449590685,
                    c=4.078873014294075,
                    z=(-0.9473684210526316+0.5263157894736841j),
                    expected=(-0.0018093573941378783+0.003481887377423739j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=2.050308316530781,
                    c=1.0651378143226575,
                    z=(-0.736842105263158-0.736842105263158j),
                    expected=(-0.00023401243818780545-1.7983496305603562e-05j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=8.077282662161238,
                    c=4.078873014294075,
                    z=(-0.5263157894736843-0.9473684210526316j),
                    expected=(0.22359773002226846-0.24092487123993353j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=2.050308316530781,
                    c=-15.963511401609862,
                    z=(-0.9473684210526316-0.5263157894736843j),
                    expected=(1.191573745740011+0.14347394589721466j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=4.0013768449590685,
                    c=-15.963511401609862,
                    z=(-0.9473684210526316-0.5263157894736843j),
                    expected=(31.822620756901784-66.09094396747611j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=8.077282662161238,
                    c=-7.93846038215665,
                    z=(-0.9473684210526316+0.5263157894736841j),
                    expected=(207.16750179245952+34.80478274924269j),
                    rtol=5e-12,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=8.095813935368371,
                    b=-7.949900487447654,
                    c=8.031683612216888,
                    z=(-0.736842105263158+0.7368421052631575j),
                    expected=(-159.62429364277145+9.154224290644898j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=-1.92872979730171,
                    c=16.056809865262608,
                    z=(-0.9473684210526316+0.5263157894736841j),
                    expected=(1.121122351247184-0.07170260470126685j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=16.087593263474208,
                    b=-0.9629749245209605,
                    c=16.056809865262608,
                    z=(-0.9473684210526316+0.5263157894736841j),
                    expected=(1.9040596681316053-0.4951799449960107j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=-1.92872979730171,
                    c=-0.906685989801748,
                    z=(-0.9473684210526316-0.5263157894736843j),
                    expected=(-14.496623497780739-21.897524523299875j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=4.080187217753502,
                    b=-3.9316537064827854,
                    c=-3.9924618758357022,
                    z=(-0.5263157894736843-0.9473684210526316j),
                    expected=(36.33473466026878+253.88728442029577j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1.0272592605282642,
                    b=-15.964218273004214,
                    c=-0.906685989801748,
                    z=(-0.9473684210526316+0.5263157894736841j),
                    expected=(1505052.5653144997-50820766.81043443j),
                    rtol=1e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=4.0013768449590685,
                    c=1.0651378143226575,
                    z=(-0.5263157894736843+0.9473684210526314j),
                    expected=(-127.79407519260877-28.69899444941112j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=8.077282662161238,
                    c=16.056809865262608,
                    z=(-0.9473684210526316-0.5263157894736843j),
                    expected=(2.0623331933754976+0.741234463565458j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=8.077282662161238,
                    c=2.0397202577726152,
                    z=(-0.9473684210526316+0.5263157894736841j),
                    expected=(30.729193458862525-292.5700835046965j),
                    rtol=1e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=1.0561196186065624,
                    c=-1.9631175993998025,
                    z=(-0.5263157894736843-0.9473684210526316j),
                    expected=(1.1285917906203495-0.735264575450189j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=1.0561196186065624,
                    c=-3.9924618758357022,
                    z=(-0.736842105263158+0.7368421052631575j),
                    expected=(0.6356474446678052-0.02429663008952248j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-1.9214641416286231,
                    b=16.088264119063613,
                    c=-7.93846038215665,
                    z=(-0.736842105263158+0.7368421052631575j),
                    expected=(0.4718880510273174+0.655083067736377j),
                    rtol=1e-11,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-7.937789122896016,
                    b=-3.9316537064827854,
                    c=16.056809865262608,
                    z=(-0.9473684210526316+0.5263157894736841j),
                    expected=(-0.14681550942352714+0.16092206364265146j),
                    rtol=5e-11,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-15.964218273004214,
                    c=1.0651378143226575,
                    z=(-0.5263157894736843+0.9473684210526314j),
                    expected=(-6.436835190526225+22.883156700606182j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-0.9220024191881196,
                    b=-7.949900487447654,
                    c=4.078873014294075,
                    z=(-0.9473684210526316-0.5263157894736843j),
                    expected=(-0.7505682955068583-1.1026583264249945j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=-3.9316537064827854,
                    c=-7.93846038215665,
                    z=(-0.9473684210526316-0.5263157894736843j),
                    expected=(3.6247814989198166+2.596041360148318j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=-15.964218273004214,
                    c=-1.9631175993998025,
                    z=(-0.5263157894736843-0.9473684210526316j),
                    expected=(-59537.65287927933-669074.4342539902j),
                    rtol=5e-15,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=-3.956227226099288,
                    b=-15.964218273004214,
                    c=-1.9631175993998025,
                    z=(-0.9473684210526316-0.5263157894736843j),
                    expected=(-433084.9970266166+431088.393918521j),
                    rtol=5e-14,
                ),
            ),
            pytest.param(
                Hyp2f1TestCase(
                    a=1,
                    b=1,
                    c=4,
                    z=(3 + 4j),
                    expected=(0.49234384000963544+0.6051340616612397j),
                    rtol=5e-14,
                ),
            ),
        ]
    )
    def test_region6(self, hyp2f1_test_case):
        """|z| > 1 but not in region 5."""
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert (
            abs(z) > 1 and
            not (1 < abs(z) < 1.1 and abs(1 - z) >= 0.9 and z.real >= 0)
        )
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)


    @pytest.mark.parametrize(
        "hyp2f1_test_case",
        [
            # Broke when fixing gamma pole behavior in gh-21827
            pytest.param(
                Hyp2f1TestCase(
                    a=1.3,
                    b=-0.2,
                    c=0.3,
                    z=-2.1,
                    expected=1.8202169687521206,
                    rtol=5e-15,
                ),
            ),
        ]
    )
    def test_miscellaneous(self, hyp2f1_test_case ):
        a, b, c, z, expected, rtol = hyp2f1_test_case
        assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)

    @pytest.mark.slow
    @check_version(mpmath, "1.0.0")
    def test_test_hyp2f1(self):
        """Test that expected values match what is computed by mpmath.

        This gathers the parameters for the test cases out of the pytest marks.
        The parameters are a, b, c, z, expected, rtol, where expected should
        be the value of hyp2f1(a, b, c, z) computed with mpmath. The test
        recomputes hyp2f1(a, b, c, z) using mpmath and verifies that expected
        actually is the correct value. This allows the data for the tests to
        live within the test code instead of an external datafile, while
        avoiding having to compute the results with mpmath during the test,
        except for when slow tests are being run.
        """
        test_methods = [
            test_method for test_method in dir(self)
            if test_method.startswith('test') and
            # Filter properties and attributes (futureproofing).
            callable(getattr(self, test_method)) and
            # Filter out this test
            test_method != 'test_test_hyp2f1'
        ]
        for test_method in test_methods:
            params = self._get_test_parameters(getattr(self, test_method))
            for a, b, c, z, expected, _ in params:
                assert_allclose(mp_hyp2f1(a, b, c, z), expected, rtol=2.25e-16)

    def _get_test_parameters(self, test_method):
        """Get pytest.mark parameters for a test in this class."""
        return [
            case.values[0] for mark in test_method.pytestmark
            if mark.name == 'parametrize'
            for case in mark.args[1]
        ]

class TestHyp2f1ExtremeInputs:

    @pytest.mark.parametrize("a", [1.0, 2.0, 3.0, -np.inf, np.inf])
    @pytest.mark.parametrize("b", [3.0, 4.0, 5.0, -np.inf, np.inf])
    @pytest.mark.parametrize("c", [3.0, 5.0, 6.0, 7.0])
    @pytest.mark.parametrize("z", [4.0 + 1.0j])
    def test_inf_a_b(self, a, b, c, z):
        if np.any(np.isinf(np.asarray([a, b]))):
            assert(np.isnan(hyp2f1(a, b, c, z)))

    def test_large_a_b(self):
        assert(np.isnan(hyp2f1(10**7, 1.0, 3.0, 4.0 + 1.0j)))
        assert(np.isnan(hyp2f1(-10**7, 1.0, 3.0, 4.0 + 1.0j)))

        assert(np.isnan(hyp2f1(1.0, 10**7, 3.0, 4.0 + 1.0j)))
        assert(np.isnan(hyp2f1(1.0, -10**7, 3.0, 4.0 + 1.0j)))

        # Already correct in main but testing for surety
        assert(np.isnan(hyp2f1(np.inf, 1.0, 3.0, 4.0)))
        assert(np.isnan(hyp2f1(1.0, np.inf, 3.0, 4.0)))
